package com.lineage.server.model;

import com.lineage.server.Instance.MapLimitInstance;
import com.lineage.server.model.Instance.L1NpcInstance;
import com.lineage.server.model.Instance.L1PcInstance;
import com.lineage.server.model.map.L1Map;
import com.lineage.server.serverpackets.S_ChangeName;
import com.lineage.server.serverpackets.S_Paralysis;
import com.lineage.server.serverpackets.S_SkillSound;
import com.lineage.server.serverpackets.ServerBasePacket;
import com.lineage.server.utils.Teleportation;
import java.util.Random;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class L1Teleport {
  public static final int TELEPORT = 0;
  
  public static final int CHANGE_POSITION = 1;
  
  public static final int ADVANCED_MASS_TELEPORT = 2;
  
  public static final int CALL_CLAN = 3;
  
  public static final int[] EFFECT_SPR;
  
  public static final int[] EFFECT_TIME;
  
  private static final Log _log = LogFactory.getLog(L1Teleport.class);
  
  private static final Random _random;
  
  static {
    EFFECT_SPR = new int[] { 169, 2235, 2236, 2281 };
    EFFECT_TIME = new int[] { 280, 440, 440, 1120 };
    _random = new Random();
  }
  
  public static void teleport(L1PcInstance pc, L1Location loc, int head, boolean effectable) {
    teleport(pc, loc.getX(), loc.getY(), (short)loc.getMapId(), head, effectable, 0);
  }
  
  public static void teleport(L1PcInstance pc, L1Location loc, int head, boolean effectable, int skillType) {
    teleport(pc, loc.getX(), loc.getY(), (short)loc.getMapId(), head, effectable, skillType);
  }
  
  public static void teleport(L1PcInstance pc, int x, int y, short mapid, int head, boolean effectable) {
    teleport(pc, x, y, mapid, head, effectable, 0);
  }
  
  public static void teleport(L1PcInstance pc, int x, int y, short mapId, int head, boolean effectable, int skillType) {
    pc.setPetModel();
    if (effectable && skillType >= 0 && skillType <= EFFECT_SPR.length) {
      pc.sendPackets((ServerBasePacket)new S_ChangeName(pc, false));
      pc.sendPacketsX8((ServerBasePacket)new S_SkillSound(pc.getId(), EFFECT_SPR[skillType]));
    } 
    pc.setoldMapId(pc.getMapId());
    pc.setTeleportX(x);
    pc.setTeleportY(y);
    pc.setTeleportMapId(mapId);
    pc.setTeleportHeading(head);
    Teleportation.teleportation(pc);
    MapLimitInstance.get().setEquippedItem(pc, Integer.valueOf(mapId));
  }
  
  public static void teleportToTargetFront(L1Character cha, L1Character target, int distance) {
    int locX = target.getX();
    int locY = target.getY();
    int heading = target.getHeading();
    L1Map map = target.getMap();
    short mapId = target.getMapId();
    switch (heading) {
      case 1:
        locX += distance;
        locY -= distance;
        break;
      case 2:
        locX += distance;
        break;
      case 3:
        locX += distance;
        locY += distance;
        break;
      case 4:
        locY += distance;
        break;
      case 5:
        locX -= distance;
        locY += distance;
        break;
      case 6:
        locX -= distance;
        break;
      case 7:
        locX -= distance;
        locY -= distance;
        break;
      case 0:
        locY -= distance;
        break;
    } 
    if (map.isPassable(locX, locY, null)) {
      if (cha instanceof L1PcInstance) {
        teleport((L1PcInstance)cha, locX, locY, mapId, cha.getHeading(), true);
      } else if (cha instanceof L1NpcInstance) {
        ((L1NpcInstance)cha).teleport(locX, locY, cha.getHeading());
      } 
    } else {
      L1Location newloc = target.getLocation().randomLocation(distance, false);
      if (cha instanceof L1PcInstance) {
        teleport((L1PcInstance)cha, newloc, cha.getHeading(), true, 1);
      } else if (cha instanceof L1NpcInstance) {
        ((L1NpcInstance)cha).teleport(newloc.getX(), newloc.getY(), cha.getHeading());
      } 
    } 
  }
  
  public static void randomTeleport(L1PcInstance pc, boolean effectable) {
    try {
      L1Location newLocation = pc.getLocation().randomLocation(200, true);
      int newX = newLocation.getX();
      int newY = newLocation.getY();
      short mapId = (short)newLocation.getMapId();
      teleport(pc, newX, newY, mapId, _random.nextInt(5) + 1, effectable);
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
    } 
  }
  
  public static void randomTeleportai(L1PcInstance pc) {
    try {
      L1Location newLocation = pc.getLocation().randomLocation(200, true);
      int newX = newLocation.getX();
      int newY = newLocation.getY();
      int mapid = pc.getMapId();
      pc.setTeleportX(newX);
      pc.setTeleportY(newY);
      pc.setTeleportMapId((short)mapid);
      pc.setTeleportHeading(5);
      pc.sendPacketsAll((ServerBasePacket)new S_SkillSound(pc.getId(), 169));
      Teleportation.teleportation(pc);
      pc.setTeleport(false);
      pc.sendPackets((ServerBasePacket)new S_Paralysis(7, false));
      if (pc.hasSkillEffect(78)) {
        pc.killSkillEffectTimer(78);
        pc.startHpRegeneration();
        pc.startMpRegeneration();
      } 
      if (pc.isPathfinding())
        pc.setrandomMoveDirection(_random.nextInt(7)); 
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
    } 
  }
}
